//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.

//# SPDX-License-Identifier: GPL-3.0-or-later
use super::help::builtin_help;
use crate::arrayfunc::valid_array_reference;
use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt};
use crate::builtins::common::{
    builtin_bind_variable, builtin_usage, sh_invalidid, sh_invalidnum, sh_wrerror,
};
use crate::general::legal_identifier;
use crate::sig::{termsig_handler, throw_to_top_level};
use crate::src_common::*;
use crate::variables::{bind_var_to_int, stupidly_hack_special_variables, sv_tz};

extern "C" {
    pub fn mbtowc(pwc: *mut libc::wchar_t, s: *const libc::c_char, n: size_t) -> size_t;
    pub fn u32cconv(c: libc::c_ulong, s: *mut libc::c_char) -> libc::c_int;
}

unsafe fn QUIT() {
    if terminating_signal != 0 {
        termsig_handler(terminating_signal);
    }

    if interrupt_state != 0 {
        throw_to_top_level();
    }
}

unsafe fn PC(c: u8) {
    let mut b: [libc::c_char; 2] = [0; 2];
    tw += 1;
    b[0] = c as libc::c_char;
    if vflag != 0 {
        vbadd(b.as_ptr() as *mut libc::c_char, 1);
    } else {
        libc::putchar(c as libc::c_int);
    }
    QUIT();
}

static mut conversion_error: libc::c_int = 0;
static mut conv_buf: *mut libc::c_char = PT_NULL as *mut libc::c_char;
static mut conv_bufsize: size_t = 0;
static mut vbuf: *mut libc::c_char = PT_NULL as *mut libc::c_char;
static mut vname: *mut libc::c_char = PT_NULL as *mut libc::c_char;
static mut vflag: libc::c_int = 0;
static mut vbsize: size_t = 0;
static mut vblen: libc::c_int = 0;

static mut retval: libc::c_int = 0;
static mut tw: libc::c_long = 0;

static mut garglist: *mut WordList = PT_NULL as *mut WordList;
static mut orig_arglist: *mut WordList = PT_NULL as *mut WordList;

#[no_mangle]
pub fn printf_builtin(mut list: *mut WordList) -> i32 {
    let mut ch: libc::c_int;
    let mut fieldwidth: libc::c_int;
    let mut have_fieldwidth: libc::c_int;
    let mut precision: libc::c_int;
    let mut have_precision: libc::c_int;
    let mut arrayflags: libc::c_int;

    let mut fmt;
    let mut start;
    let mut modstart;
    let mut convch;
    let mut thisch;
    let mut nextch;
    unsafe {
        let PRETURN = |out_val: libc::c_int| {
            QUIT();
            if vflag != 0 {
                let v = builtin_bind_variable(vname, vbuf, 0);
                stupidly_hack_special_variables(vname);
                if v.is_null()
                    || ((*v).attributes & att_readonly) != 0
                    || ((*v).attributes & att_noassign) != 0
                {
                    return EXECUTION_FAILURE;
                }
            }
            if conv_bufsize > 4096 {
                libc::free(conv_buf as *mut c_void);
                conv_bufsize = 0;
                conv_buf = PT_NULL as *mut libc::c_char;
            }

            if vbsize > 4096 {
                libc::free(vbuf as *mut c_void);
                vbsize = 0;
                vbuf = PT_NULL as *mut libc::c_char;
            } else if !vbuf.is_null() {
                *vbuf = 0;
            }

            if libc::ferror(stdout) == 0 {
                libc::fflush(stdout);
            }
            QUIT();
            if libc::ferror(stdout) != 0 {
                sh_wrerror();
                libc::clearerr(stdout);
                return EXECUTION_FAILURE;
            }

            return out_val;
        };

        vflag = 0;
        reset_internal_getopt();
        let opt_str = CString::new("v:").unwrap();
        let mut opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char);
        while opt != -1 {
            let opt_char: char = char::from(opt as u8);
            match opt_char {
                'v' => {
                    vname = list_optarg;
                    arrayflags = if assoc_expand_once != 0 {
                        VA_NOEXPAND | VA_ONEWORD
                    } else {
                        0
                    };
                    if legal_identifier(vname) != 0 || valid_array_reference(vname, arrayflags) != 0
                    {
                        vflag = 1;
                        if vbsize == 0 {
                            vbsize = 16;
                            vbuf = malloc(16) as *mut libc::c_char;
                        }
                        vblen = 0;
                        if !vbuf.is_null() {
                            *vbuf = 0;
                        }
                    } else {
                        sh_invalidid(vname);
                        return EX_USAGE;
                    }
                }
                _ => {
                    if opt == -99 {
                        builtin_help();
                        return EX_USAGE;
                    }
                    builtin_usage();
                    return EX_USAGE;
                }
            }
            opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char);
        }
        list = loptend;

        if list.is_null() {
            builtin_usage();
            return EX_USAGE;
        }

        if vflag != 0
            && !((*(*list).word).word.is_null())
            && *(*(*list).word).word == b'\0' as libc::c_char
        {
            let v = builtin_bind_variable(vname, "\0".as_ptr() as *mut libc::c_char, 0);
            stupidly_hack_special_variables(vname);
            return if v.is_null()
                || ((*v).attributes & att_readonly) != 0
                || ((*v).attributes & att_noassign) != 0
            {
                EXECUTION_FAILURE
            } else {
                EXECUTION_SUCCESS
            };
        }

        if (*(*list).word).word.is_null() || *(*(*list).word).word == b'\0' as libc::c_char {
            return EXECUTION_SUCCESS;
        }

        let format = (*(*list).word).word;
        tw = 0;

        garglist = (*list).next;
        orig_arglist = (*list).next;

        if format.is_null() || *format == 0 {
            return EXECUTION_SUCCESS;
        }

        'outer: loop {
            tw = 0;
            fmt = format;

            while *fmt != 0 {
                precision = 0;
                fieldwidth = 0;
                have_fieldwidth = 0;
                have_precision = 0;

                if *fmt == b'\\' as libc::c_char {
                    fmt = (fmt as usize + 1) as *mut libc::c_char;

                    let mbch: [libc::c_char; 25] = [0; 25];
                    let mblen: libc::c_int = 0;
                    fmt = (fmt as usize
                        + tescape(
                            fmt,
                            mbch.as_ptr() as *mut libc::c_char,
                            std::mem::transmute(&mblen),
                            PT_NULL as *mut libc::c_int,
                        ) as usize) as *mut libc::c_char;
                    let mut mbind = 0;

                    while mbind < mblen {
                        PC(mbch[mbind as usize] as u8);
                        mbind += 1;
                    }
                    fmt = (fmt as usize - 1) as *mut libc::c_char;

                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                    continue;
                }

                if *fmt != b'%' as libc::c_char {
                    PC(*fmt as u8);

                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                    continue;
                }

                start = fmt;
                fmt = (fmt as usize + 1) as *mut libc::c_char;
                if *fmt == b'%' as libc::c_char {
                    PC(b'%');

                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                    continue;
                }

                while *fmt != 0
                    && !(strchr(
                        "#'-+ 0\0".as_ptr() as *const libc::c_char,
                        *fmt as libc::c_int,
                    )
                    .is_null())
                {
                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                }

                if *fmt == b'*' as libc::c_char {
                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                    have_fieldwidth = 1;
                    fieldwidth = getint();
                } else {
                    while IS_DIGITAL!(*fmt) {
                        fmt = (fmt as usize + 1) as *mut libc::c_char;
                    }
                }

                if *fmt == b'.' as libc::c_char {
                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                    if *fmt == b'*' as libc::c_char {
                        fmt = (fmt as usize + 1) as *mut libc::c_char;
                        have_precision = 1;
                        precision = getint();
                    } else {
                        if *fmt == b'-' as libc::c_char {
                            fmt = (fmt as usize + 1) as *mut libc::c_char;
                        }
                        while IS_DIGITAL!(*fmt) {
                            fmt = (fmt as usize + 1) as *mut libc::c_char;
                        }
                    }
                }

                modstart = fmt;
                while *fmt != 0
                    && !(strchr(
                        "hjlLtz\0".as_ptr() as *const libc::c_char,
                        *fmt as libc::c_int,
                    )
                    .is_null())
                {
                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                }

                if *fmt == 0 {
                    builtin_error(
                        "`%s': missing format character\0".as_ptr() as *const libc::c_char,
                        start,
                    );
                    return PRETURN(EXECUTION_FAILURE);
                }

                convch = *fmt;
                thisch = *modstart;
                nextch = *((modstart as usize + 1) as *mut libc::c_char);
                *modstart = convch;
                *((modstart as usize + 1) as *mut libc::c_char) = b'\0' as libc::c_char;

                QUIT();
                let format_type = convch as u8;
                match format_type {
                    b'c' => {
                        let p = getchr();
                        let f = start;
                        libc::clearerr(stdout);
                        let PF = || {
                            let nw: libc::c_int;
                            if vflag == 0 {
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = libc::printf(f, fieldwidth, precision, p);
                                } else if have_fieldwidth != 0 {
                                    nw = libc::printf(f, fieldwidth, p);
                                } else if have_precision != 0 {
                                    nw = libc::printf(f, precision, p);
                                } else {
                                    nw = libc::printf(f, p);
                                }
                            } else {
                                let vbsnprintf2 = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        have_fieldwidth,
                                        have_precision,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            have_fieldwidth,
                                            have_precision,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf1 = |x: libc::c_int| {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        x,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            x,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = vbsnprintf2();
                                } else if have_fieldwidth != 0 {
                                    nw = vbsnprintf1(fieldwidth);
                                } else if have_precision != 0 {
                                    nw = vbsnprintf1(precision);
                                } else {
                                    nw = vbsnprintf();
                                }
                            }
                            tw += nw as libc::c_long;
                        };
                        PF();
                        QUIT();
                        if libc::ferror(stdout) != 0 {
                            sh_wrerror();
                            libc::clearerr(stdout);
                            return EXECUTION_FAILURE;
                        }
                    }
                    b's' => {
                        let p = getstr();
                        let f = start;
                        libc::clearerr(stdout);
                        let PF = || {
                            let nw: libc::c_int;
                            if vflag == 0 {
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = libc::printf(f, fieldwidth, precision, p);
                                } else if have_fieldwidth != 0 {
                                    nw = libc::printf(f, fieldwidth, p);
                                } else if have_precision != 0 {
                                    nw = libc::printf(f, precision, p);
                                } else {
                                    nw = libc::printf(f, p);
                                }
                            } else {
                                let vbsnprintf2 = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        have_fieldwidth,
                                        have_precision,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            have_fieldwidth,
                                            have_precision,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf1 = |x: libc::c_int| {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        x,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            x,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = vbsnprintf2();
                                } else if have_fieldwidth != 0 {
                                    nw = vbsnprintf1(fieldwidth);
                                } else if have_precision != 0 {
                                    nw = vbsnprintf1(precision);
                                } else {
                                    nw = vbsnprintf();
                                }
                            }
                            tw += nw as libc::c_long;
                        };
                        PF();
                        QUIT();
                        if libc::ferror(stdout) != 0 {
                            sh_wrerror();
                            libc::clearerr(stdout);
                            return EXECUTION_FAILURE;
                        }
                    }
                    b'(' => {
                        *((modstart as usize + 1) as *mut libc::c_char) = nextch;
                        let timefmt = malloc(libc::strlen(fmt) + 3) as *mut libc::c_char;
                        fmt = (fmt as usize + 1) as *mut libc::c_char;
                        let mut t = timefmt;
                        let mut n = 1;
                        while *fmt != 0 {
                            if *fmt == b'(' as libc::c_char {
                                n += 1;
                            } else if *fmt == b')' as libc::c_char {
                                n -= 1;
                            }
                            if n == 0 {
                                break;
                            }
                            *t = *fmt;
                            t = (t as usize + 1) as *mut libc::c_char;
                            fmt = (fmt as usize + 1) as *mut libc::c_char;
                        }
                        *t = b'\0' as libc::c_char;
                        fmt = (fmt as usize + 1) as *mut libc::c_char;
                        if *fmt != b'T' as libc::c_char {
                            builtin_warning(
                                "`%c': invalid time format specification\0".as_ptr()
                                    as *const libc::c_char,
                                *fmt as libc::c_int,
                            );
                            fmt = start;
                            libc::free(timefmt as *mut c_void);
                            PC(*fmt as u8);

                            fmt = (fmt as usize + 1) as *mut libc::c_char;
                            continue;
                        }
                        if *timefmt == b'\0' as libc::c_char {
                            *timefmt = b'%' as libc::c_char;
                            *((timefmt as usize + 1) as *mut libc::c_char) = b'X' as libc::c_char;
                            *((timefmt as usize + 2) as *mut libc::c_char) = b'\0' as libc::c_char;
                        }

                        let arg = if !garglist.is_null() { getintmax() } else { -1 };
                        let mut secs: libc::time_t;
                        if arg == -1 {
                            secs = libc::time(0 as *mut libc::time_t);
                        } else if arg == -2 {
                            secs = shell_start_time;
                        } else {
                            secs = arg;
                        }

                        sv_tz("TZ\0".as_ptr() as *mut libc::c_char);
                        let mut tm = libc::localtime(std::mem::transmute(&secs));
                        if tm.is_null() {
                            secs = 0;
                            tm = libc::localtime(std::mem::transmute(&secs));
                        }
                        let mut timebuf: [libc::c_char; 128] = [0; 128];
                        let mut n: libc::c_int = if !tm.is_null() {
                            strftime(timebuf.as_ptr() as *mut libc::c_char, 128, timefmt, tm)
                                as libc::c_int
                        } else {
                            0
                        };
                        libc::free(timefmt as *mut c_void);
                        if n == 0 {
                            timebuf[0] = b'\0' as libc::c_char;
                        } else {
                            timebuf[127] = b'\0' as libc::c_char;
                        }

                        *modstart = b's' as libc::c_char;
                        *((modstart as usize + 1) as *mut libc::c_char) = b'\0' as libc::c_char;
                        n = printstr(
                            start,
                            timebuf.as_ptr() as *mut libc::c_char,
                            libc::strlen(timebuf.as_ptr()) as libc::c_int,
                            fieldwidth,
                            precision,
                        );
                        if n < 0 {
                            if libc::ferror(stdout) == 0 {
                                sh_wrerror();
                                libc::clearerr(stdout);
                            }
                            return PRETURN(EXECUTION_FAILURE);
                        }
                    }
                    b'n' => {
                        let var = getstr();
                        if !var.is_null() && *var != 0 {
                            if legal_identifier(var) != 0 {
                                bind_var_to_int(var, tw);
                            } else {
                                sh_invalidid(var);
                                return PRETURN(EXECUTION_FAILURE);
                            }
                        }
                    }
                    b'b' => {
                        let rlen: libc::c_int = 0;
                        let mut r: libc::c_int = 0;
                        ch = 0;
                        let p = getstr();
                        let xp = bexpand(
                            p,
                            libc::strlen(p) as libc::c_int,
                            std::mem::transmute(&ch),
                            std::mem::transmute(&rlen),
                        );
                        if !xp.is_null() {
                            r = printstr(start, xp, rlen, fieldwidth, precision);
                            if r < 0 {
                                if libc::ferror(stdout) == 0 {
                                    sh_wrerror();
                                    libc::clearerr(stdout);
                                }
                                retval = EXECUTION_FAILURE;
                            }
                            libc::free(xp as *mut c_void);
                        }
                        if ch != 0 || r < 0 {
                            return PRETURN(retval);
                        }
                    }
                    b'q' => {
                        let mut r: libc::c_int = 0;
                        let xp: *mut libc::c_char;
                        let p = getstr();
                        if !p.is_null() && *p == 0 {
                            xp = savestring!(b"''\0".as_ptr() as *mut libc::c_char);
                            //xp = savestring(b"''\0".as_ptr() as *const libc::c_char);
                        } else if ansic_shouldquote(p) != 0 {
                            xp = ansic_quote(p, 0, PT_NULL as *mut libc::c_int);
                        } else {
                            xp = sh_backslash_quote(p, PT_NULL as *mut libc::c_char, 3);
                        }
                        if !xp.is_null() {
                            r = printstr(
                                start,
                                xp,
                                libc::strlen(xp) as libc::c_int,
                                fieldwidth,
                                precision,
                            );
                            if r < 0 {
                                if libc::ferror(stdout) == 0 {
                                    sh_wrerror();
                                    libc::clearerr(stdout);
                                }
                                libc::free(xp as *mut c_void);
                            }
                        }
                        if r < 0 {
                            return PRETURN(EXECUTION_FAILURE);
                        }
                    }
                    b'd' | b'i' => {
                        let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1);
                        let p = getintmax();
                        libc::clearerr(stdout);
                        let PF = || {
                            let nw: libc::c_int;
                            if vflag == 0 {
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = libc::printf(f, fieldwidth, precision, p);
                                } else if have_fieldwidth != 0 {
                                    nw = libc::printf(f, fieldwidth, p);
                                } else if have_precision != 0 {
                                    nw = libc::printf(f, precision, p);
                                } else {
                                    nw = libc::printf(f, p);
                                }
                            } else {
                                let vbsnprintf2 = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        have_fieldwidth,
                                        have_precision,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            have_fieldwidth,
                                            have_precision,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf1 = |x: libc::c_int| {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        x,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            x,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = vbsnprintf2();
                                } else if have_fieldwidth != 0 {
                                    nw = vbsnprintf1(fieldwidth);
                                } else if have_precision != 0 {
                                    nw = vbsnprintf1(precision);
                                } else {
                                    nw = vbsnprintf();
                                }
                            }
                            tw += nw as libc::c_long;
                        };
                        PF();
                        QUIT();
                        if libc::ferror(stdout) != 0 {
                            sh_wrerror();
                            libc::clearerr(stdout);
                            return EXECUTION_FAILURE;
                        }
                    }
                    b'o' | b'u' | b'x' | b'X' => {
                        let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1);
                        let p = getuintmax();
                        libc::clearerr(stdout);
                        let PF = || {
                            let nw: libc::c_int;
                            if vflag == 0 {
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = libc::printf(f, fieldwidth, precision, p);
                                } else if have_fieldwidth != 0 {
                                    nw = libc::printf(f, fieldwidth, p);
                                } else if have_precision != 0 {
                                    nw = libc::printf(f, precision, p);
                                } else {
                                    nw = libc::printf(f, p);
                                }
                            } else {
                                let vbsnprintf2 = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        have_fieldwidth,
                                        have_precision,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            have_fieldwidth,
                                            have_precision,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf1 = |x: libc::c_int| {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        x,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            x,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = vbsnprintf2();
                                } else if have_fieldwidth != 0 {
                                    nw = vbsnprintf1(fieldwidth);
                                } else if have_precision != 0 {
                                    nw = vbsnprintf1(precision);
                                } else {
                                    nw = vbsnprintf();
                                }
                            }
                            tw += nw as libc::c_long;
                        };
                        PF();
                        QUIT();
                        if libc::ferror(stdout) != 0 {
                            sh_wrerror();
                            libc::clearerr(stdout);
                            return EXECUTION_FAILURE;
                        }
                    }
                    b'e' | b'E' | b'f' | b'F' | b'g' | b'G' | b'a' | b'A' => {
                        let p = getfloatmax();
                        let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1);
                        libc::clearerr(stdout);
                        let PF = || {
                            let nw: libc::c_int;
                            if vflag == 0 {
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = libc::printf(f, fieldwidth, precision, p);
                                } else if have_fieldwidth != 0 {
                                    nw = libc::printf(f, fieldwidth, p);
                                } else if have_precision != 0 {
                                    nw = libc::printf(f, precision, p);
                                } else {
                                    nw = libc::printf(f, p);
                                }
                            } else {
                                let vbsnprintf2 = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        have_fieldwidth,
                                        have_precision,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            have_fieldwidth,
                                            have_precision,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf1 = |x: libc::c_int| {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        x,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            x,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                let vbsnprintf = || {
                                    let mut blen: libc::c_int;
                                    blen = libc::snprintf(
                                        (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                        (vbsize - vblen as size_t) as usize,
                                        f,
                                        p,
                                    );
                                    let nlen: size_t = vblen as size_t + blen as size_t + 1;
                                    if nlen > vbsize {
                                        vbsize = ((nlen as size_t + 63) >> 6) << 6;
                                        vbuf = realloc(vbuf as *mut c_void, vbsize as usize)
                                            as *mut libc::c_char;
                                        blen = libc::snprintf(
                                            (vbuf as usize + vblen as usize) as *mut libc::c_char,
                                            (vbsize - vblen as size_t) as usize,
                                            f,
                                            p,
                                        );
                                    }
                                    vblen += blen;
                                    *((vbuf as usize + vblen as usize) as *mut libc::c_char) =
                                        b'0' as libc::c_char;
                                    blen
                                };
                                if have_fieldwidth != 0 && have_precision != 0 {
                                    nw = vbsnprintf2();
                                } else if have_fieldwidth != 0 {
                                    nw = vbsnprintf1(fieldwidth);
                                } else if have_precision != 0 {
                                    nw = vbsnprintf1(precision);
                                } else {
                                    nw = vbsnprintf();
                                }
                            }
                            tw += nw as libc::c_long;
                        };
                        PF();
                        QUIT();
                        if libc::ferror(stdout) != 0 {
                            sh_wrerror();
                            libc::clearerr(stdout);
                            return EXECUTION_FAILURE;
                        }
                    }
                    _ => {
                        builtin_error(
                            "`%c': invalid format character\0".as_ptr() as *const libc::c_char,
                            convch as libc::c_int,
                        );
                        return PRETURN(EXECUTION_FAILURE);
                    }
                }

                *modstart = thisch;
                *((modstart as usize + 1) as *mut libc::c_char) = nextch;

                fmt = (fmt as usize + 1) as *mut libc::c_char;
            }

            if libc::ferror(stdout) != 0 {
                return PRETURN(EXECUTION_FAILURE);
            }

            if !garglist.is_null() && garglist != (*list).next {
                continue 'outer;
            } else {
                break 'outer;
            }
        }

        if conversion_error != 0 {
            retval = EXECUTION_FAILURE;
        }

        return PRETURN(retval);
    }
}

fn hexvalue(c: u8) -> libc::c_int {
    return (if (c) >= b'a' && (c) <= b'f' {
        (c) - b'a' + 10
    } else if (c) >= b'A' && (c) <= b'F' {
        (c) - b'A' + 10
    } else {
        (c) - b'0'
    }) as i32;
}

fn printstr(
    mut fmt: *mut libc::c_char,
    mut string: *mut libc::c_char,
    len: libc::c_int,
    fieldwidth: libc::c_int,
    precision: libc::c_int,
) -> libc::c_int {
    unsafe {
        if string.is_null() {
            string = "\0".as_ptr() as *mut libc::c_char;
        }

        if *fmt == b'%' as libc::c_char {
            fmt = (fmt as usize + 1) as *mut libc::c_char;
        }

        let mut ljust: libc::c_int = 0;
        let mut fw: libc::c_int = 0;
        let mut mfw: libc::c_long = 0;
        let mut pr: libc::c_int = -1;
        let mut mpr: libc::c_long = -1;

        while !(strchr(
            "#'-+ 0\0".as_ptr() as *const libc::c_char,
            *fmt as libc::c_int,
        )
        .is_null())
        {
            if *fmt == b'-' as libc::c_char {
                ljust = 1;
            }
            fmt = (fmt as usize + 1) as *mut libc::c_char;
        }

        if *fmt == b'*' as libc::c_char {
            fmt = (fmt as usize + 1) as *mut libc::c_char;
            fw = fieldwidth;
            if fw < 0 {
                fw = -fw;
                ljust = 1;
            }
        } else if IS_DIGITAL!(*fmt) {
            mfw = (*fmt - b'0' as libc::c_char) as libc::c_long;
            fmt = (fmt as usize + 1) as *mut libc::c_char;
            while IS_DIGITAL!(*fmt) {
                mfw = mfw * 10 + (*fmt - b'0' as libc::c_char) as libc::c_long;
                fmt = (fmt as usize + 1) as *mut libc::c_char;
            }
            fw = if mfw < 0 || mfw > (libc::INT_MAX as libc::c_long) {
                libc::INT_MAX
            } else {
                mfw as libc::c_int
            };
        }

        if *fmt == b'.' as libc::c_char {
            fmt = (fmt as usize + 1) as *mut libc::c_char;
            if *fmt == b'*' as libc::c_char {
                fmt = (fmt as usize + 1) as *mut libc::c_char;
                pr = precision;
            } else if IS_DIGITAL!(*fmt) {
                mpr = (*fmt - b'0' as libc::c_char) as libc::c_long;
                fmt = (fmt as usize + 1) as *mut libc::c_char;
                while IS_DIGITAL!(*fmt) {
                    mpr = mpr * 10 + (*fmt - b'0' as libc::c_char) as libc::c_long;
                    fmt = (fmt as usize + 1) as *mut libc::c_char;
                }
                pr = if mpr < 0 || mpr > (libc::INT_MAX as libc::c_long) {
                    libc::INT_MAX
                } else {
                    mpr as libc::c_int
                };
            } else {
                pr = 0;
            }
        }

        let nc = if pr >= 0 && pr <= len { pr } else { len };
        let mut padlen = fw - nc;
        if padlen < 0 {
            padlen = 0;
        }
        if ljust != 0 {
            padlen = -padlen;
        }

        while padlen > 0 {
            PC(b' ');
            padlen -= 1;
        }

        for i in 0..nc {
            PC(*((string as usize + i as usize) as *mut libc::c_char) as u8);
        }

        return 0;
    }
}

fn tescape(
    estart: *mut libc::c_char,
    cp: *mut libc::c_char,
    lenp: *mut libc::c_int,
    sawc: *mut libc::c_int,
) -> libc::c_int {
    let mut p: *mut libc::c_char = estart;
    let mut evalue: libc::c_int;
    let mut temp: libc::c_int;
    let mut uvalue: libc::c_ulong;
    unsafe {
        if !lenp.is_null() {
            *lenp = 1;
        }

        let c = *p as u8;
        p = (p as usize + 1) as *mut libc::c_char;
        match c {
            b'a' => *cp = 7,
            b'b' => *cp = 8,
            b'e' | b'E' => *cp = 27,
            b'f' => *cp = 12,
            b'n' => *cp = 10,
            b'r' => *cp = 13,
            b't' => *cp = 9,
            b'v' => *cp = 11,
            b'0'..=b'7' => {
                evalue = (c - b'0') as libc::c_int;
                temp = 2 + (evalue == 0 && !sawc.is_null()) as libc::c_int;
                while *p >= b'0' as libc::c_char && *p <= b'7' as libc::c_char && temp != 0 {
                    temp -= 1;
                    evalue = (evalue * 8) + (*p - b'0' as libc::c_char) as libc::c_int;
                    p = (p as usize + 1) as *mut libc::c_char;
                }

                *cp = (evalue & 0xff) as libc::c_char;
            }
            b'x' => {
                temp = 2;
                evalue = 0;
                while libc::isdigit(*p as libc::c_int) != 0 && temp != 0 {
                    temp -= 1;
                    evalue = (evalue * 16) + hexvalue(*p as u8);
                    p = (p as usize + 1) as *mut libc::c_char;
                }

                if p as usize == (estart as usize + 1) {
                    builtin_error("missing hex digit for \\x\0".as_ptr() as *const libc::c_char);
                    *cp = b'\\' as libc::c_char;
                    return 0;
                }
                *cp = (evalue & 0xff) as libc::c_char;
            }
            b'u' | b'U' => {
                temp = if c == b'u' { 4 } else { 8 };
                uvalue = 0;
                while libc::isdigit(*p as libc::c_int) != 0 && temp != 0 {
                    temp -= 1;
                    uvalue = (uvalue * 16) + hexvalue(*p as u8) as libc::c_ulong;
                    p = (p as usize + 1) as *mut libc::c_char;
                }

                if p as usize == (estart as usize + 1) {
                    builtin_error(
                        "missing unicode digit for \\%c\0".as_ptr() as *const libc::c_char,
                        c as libc::c_int,
                    );
                    *cp = b'\\' as libc::c_char;
                    return 0;
                }
                if uvalue <= 0x7f {
                    *cp = uvalue as libc::c_char;
                } else {
                    temp = u32cconv(uvalue, cp);
                    *((cp as usize + temp as usize) as *mut libc::c_char) = b'\0' as libc::c_char;
                    if !lenp.is_null() {
                        *lenp = temp;
                    }
                }
            }
            b'\\' => *cp = c as libc::c_char,
            b'\'' | b'"' | b'?' => {
                if sawc.is_null() {
                    *cp = c as libc::c_char;
                } else {
                    *cp = b'\\' as libc::c_char;
                    return 0;
                }
            }
            b'c' => {
                if sawc.is_null() {
                    *sawc = 1;
                } else {
                    *cp = b'\\' as libc::c_char;
                    return 0;
                }
            }
            _ => {
                *cp = b'\\' as libc::c_char;
                return 0;
            }
        }
    }
    return (p as usize - estart as usize) as libc::c_int;
}

fn bexpand(
    string: *mut libc::c_char,
    len: libc::c_int,
    sawc: *mut libc::c_int,
    lenp: *mut libc::c_int,
) -> *mut libc::c_char {
    let mut mbch: [libc::c_char; 25];
    let mblen: libc::c_int = 0;

    let ret: *mut libc::c_char;
    let mut r: *mut libc::c_char;
    let mut s: *mut libc::c_char;
    let mut c: libc::c_char;
    unsafe {
        if string.is_null() || len == 0 {
            if !sawc.is_null() {
                *sawc = 0;
            }
            if !lenp.is_null() {
                *lenp = 0;
            }
            ret = malloc(1) as *mut libc::c_char;
            *ret = b'\0' as libc::c_char;
            return ret;
        }

        ret = malloc((len + 1) as usize) as *mut libc::c_char;
        r = ret;
        s = string;
        while !s.is_null() && *s != 0 {
            c = *s as libc::c_char;
            s = (s as usize + 1) as *mut libc::c_char;
            if c != b'\\' as libc::c_char || *s == b'\0' as libc::c_char {
                *r = c;
                r = (r as usize + 1) as *mut libc::c_char;
                continue;
            }

            let temp: libc::c_int = 0;
            mbch = [0; 25];
            let n = tescape(
                s,
                mbch.as_mut_ptr() as *mut libc::c_char,
                std::mem::transmute(&mblen),
                std::mem::transmute(&temp),
            );
            s = (s as usize + n as usize) as *mut libc::c_char;

            if temp != 0 {
                if !sawc.is_null() {
                    *sawc = 1;
                }
                break;
            }

            for mbind in 0..mblen {
                *r = mbch[mbind as usize];
                r = (r as usize + 1) as *mut libc::c_char;
            }
        }

        *r = b'\0' as libc::c_char;
        if !lenp.is_null() {
            *lenp = (r as usize - ret as usize) as libc::c_int;
        }
    }
    return ret;
}

fn vbadd(buf: *mut libc::c_char, blen: libc::c_int) -> *mut libc::c_char {
    unsafe {
        let nlen: size_t = vblen as size_t + blen as size_t + 1;
        if nlen >= vbsize {
            vbsize = ((nlen + 63) >> 6) << 6;
            vbuf = realloc(vbuf as *mut c_void, vbsize as usize) as *mut libc::c_char;
        }

        if blen == 1 {
            *((vbuf as usize + vblen as usize) as *mut libc::c_char) = *buf;
            vblen += 1;
        } else if blen > 1 {
            libc::memcpy(
                (vbuf as usize + vblen as usize) as *mut c_void,
                buf as *mut c_void,
                blen as usize,
            );
            vblen += blen;
        }
        *((vbuf as usize + vblen as usize) as *mut libc::c_char) = b'\0' as libc::c_char;

        return vbuf;
    }
}

fn printf_erange(s: *mut libc::c_char) {
    unsafe {
        builtin_error(
            "warning: %s: %s\0".as_ptr() as *const libc::c_char,
            s,
            libc::strerror(libc::ERANGE),
        );
    }
}

fn mklong(str: *mut libc::c_char, modifiers: *mut libc::c_char, mlen: size_t) -> *mut libc::c_char {
    unsafe {
        let slen = libc::strlen(str);
        let len = slen + mlen as usize + 1;

        if len as size_t > conv_bufsize {
            conv_bufsize = (((len + 1023) >> 10) << 10) as size_t;
            conv_buf =
                libc::realloc(conv_buf as *mut c_void, conv_bufsize as usize) as *mut libc::c_char;
        }

        libc::memcpy(conv_buf as *mut c_void, str as *mut c_void, slen - 1);
        libc::memcpy(
            (conv_buf as usize + slen - 1) as *mut c_void,
            modifiers as *mut c_void,
            mlen as usize,
        );

        *((conv_buf as usize + len - 2) as *mut libc::c_char) =
            *((str as usize + slen - 1) as *mut libc::c_char);
        *((conv_buf as usize + len - 1) as *mut libc::c_char) = b'\0' as libc::c_char;

        return conv_buf;
    }
}

fn getchr() -> libc::c_int {
    unsafe {
        if garglist.is_null() {
            return b'\0' as libc::c_int;
        }

        let ret = *(*(*garglist).word).word as libc::c_int;
        garglist = (*garglist).next;
        return ret;
    }
}

fn getstr() -> *mut libc::c_char {
    unsafe {
        if garglist.is_null() {
            return "\0".as_ptr() as *mut libc::c_char;
        }

        let ret = (*(*garglist).word).word;
        garglist = (*garglist).next;
        return ret;
    }
}

fn getint() -> libc::c_int {
    let mut ret = getintmax();
    unsafe {
        if garglist.is_null() {
            return ret as libc::c_int;
        }
        if ret > libc::INT_MAX as libc::c_long {
            printf_erange((*(*garglist).word).word);
            ret = libc::INT_MAX as libc::c_long;
        } else if ret < libc::INT_MIN as libc::c_long {
            printf_erange((*(*garglist).word).word);
            ret = libc::INT_MIN as libc::c_long;
        }
    }
    return ret as libc::c_int;
}

fn getintmax() -> libc::c_long {
    unsafe {
        if garglist.is_null() {
            return 0;
        }

        if *(*(*garglist).word).word == b'\'' as libc::c_char
            || *(*(*garglist).word).word == b'"' as libc::c_char
        {
            return asciicode();
        }

        let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char;
        *libc::__errno_location() = 0;
        let ret = libc::strtol((*(*garglist).word).word, std::mem::transmute(&ep), 0);
        if *ep != 0 {
            sh_invalidnum((*(*garglist).word).word);
            conversion_error = 1;
        } else if *libc::__errno_location() == libc::ERANGE {
            printf_erange((*(*garglist).word).word);
        }
        garglist = (*garglist).next;
        return ret;
    }
}

fn getuintmax() -> libc::c_ulong {
    unsafe {
        if garglist.is_null() {
            return 0;
        }

        if *(*(*garglist).word).word == b'\'' as libc::c_char
            || *(*(*garglist).word).word == b'"' as libc::c_char
        {
            return asciicode() as libc::c_ulong;
        }

        *libc::__errno_location() = 0;
        let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char;
        let ret = libc::strtoul((*(*garglist).word).word, std::mem::transmute(&ep), 0);
        if *ep != 0 {
            sh_invalidnum((*(*garglist).word).word);
            conversion_error = 1;
        } else if *libc::__errno_location() == libc::ERANGE {
            printf_erange((*(*garglist).word).word);
        }
        garglist = (*garglist).next;
        return ret;
    }
}

fn getfloatmax() -> f64 {
    let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char;
    unsafe {
        if garglist.is_null() {
            return 0.0;
        }

        if *(*(*garglist).word).word == b'\'' as libc::c_char
            || *(*(*garglist).word).word == b'\"' as libc::c_char
        {
            return asciicode() as f64;
        }

        *libc::__errno_location() = 0;
        let ret = libc::strtod((*(*garglist).word).word, std::mem::transmute(&ep));
        if *ep != 0 {
            sh_invalidnum((*(*garglist).word).word);
            conversion_error = 1;
        } else if *libc::__errno_location() == libc::ERANGE {
            printf_erange((*(*garglist).word).word);
        }

        garglist = (*garglist).next;

        return ret;
    }
}

fn asciicode() -> libc::c_long {
    unsafe {
        let ch: libc::c_long;
        //let state: mbstate_t = std::mem::zeroed();
        let slen = libc::strlen((*(*garglist).word).word);
        let wc: libc::wchar_t = 0;
        let mblength = mbtowc(
            std::mem::transmute(&wc),
            ((*(*garglist).word).word as usize + 1) as *mut libc::c_char,
            slen as size_t,
        );
        if mblength > 0 {
            ch = wc as libc::c_long;
        } else {
            ch = *(((*(*garglist).word).word as usize + 1) as *mut libc::c_char) as libc::c_long;
        }

        garglist = (*garglist).next;

        return ch;
    }
}
